grammar MapDSL;

// Parser Rules
program
    : statement* EOF
    ;

statement
    : variableDeclaration
    | ifStatement
    | expressionStatement
    ;

variableDeclaration
    : 'var' IDENTIFIER '=' expression ';'
    ;

ifStatement
    : 'if' '(' expression ')' block ('else' block)?
    ;

block
    : '{' statement* '}'
    ;

expressionStatement
    : expression ';'
    ;

expression
    : primary                                                      #primaryExpr
    | expression '[' expression ']'                                #arrayAccessExpr
    | expression '.' IDENTIFIER '(' (expression (',' expression)*)? ')'  #methodCallExpr
    | 'reg_match' '(' expression ',' expression ')'                #regexMatchExpr
    | 'reg_replace' '(' expression ',' expression ',' expression ')'    #regexReplaceExpr
    | 'reg_findall' '(' expression ',' expression ')'              #regexFindAllExpr
    | 'size' '(' expression ')'                                    #arraySizeExpr
    | '!' expression                                              #notExpr
    | expression op=('*'|'/'|'%') expression                      #multiplicativeExpr
    | expression op=('+'|'-') expression                          #additiveExpr
    | expression op=('>'|'>='|'<'|'<=') expression               #relationalExpr
    | expression op=('=='|'!=') expression                        #equalityExpr
    | expression '&&' expression                                  #andExpr
    | expression '||' expression                                  #orExpr
    ;

primary
    : '(' expression ')'
    | BOOLEAN
    | INTEGER
    | FLOAT
    | STRING
    | STRING_ARRAY
    | IDENTIFIER
    | 'data'
    ;

// Lexer Rules
BOOLEAN: 'true' | 'false';
INTEGER: [0-9]+;
FLOAT: [0-9]+ '.' [0-9]+;
STRING: '"' (~["\r\n] | '\\"')* '"';
STRING_ARRAY
    : '[' WS* (STRING (WS* ',' WS* STRING)*)? WS* ']'
    ;
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;
WS: [ \t\r\n]+ -> skip;
COMMENT: '//' ~[\r\n]* -> skip;
MULTILINE_COMMENT: '/*' .*? '*/' -> skip; 